package com.org.api.admin.controller;

import com.github.devgcoder.locache.LoCacheable;
import com.org.api.admin.entity.vo.IndexVo;
import com.org.api.admin.entity.vo.TestVo;
import com.org.api.admin.service.TestService;
import com.org.platform.model.ResultModel;
import com.org.platform.support.conponents.Lock;
import com.org.platform.support.conponents.kafka.KafkaComponent;
import com.org.platform.support.conponents.request.repeat.RequestRepeatCheck;
import com.org.platform.utils.CommonUtil;
import com.org.platform.utils.LocalDateUtil;
import com.org.platform.utils.http.HttpTest;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;

import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * @author duheng
 * @Date 2021/11/17 15:41
 */

@Slf4j
@RestController
public class TestController {

    @Autowired
    private TestService testService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private KafkaComponent kafkaComponent;

    @Autowired
    private Lock lock;

    private static int a;

    public class LockTestInfo implements Runnable {
        private CountDownLatch countDownLatch;

        private int count;

        private Lock lock;

        public LockTestInfo(CountDownLatch countDownLatch, int count, Lock lock) {
            this.countDownLatch = countDownLatch;
            this.count = count;
            this.lock = lock;
        }

        @Override
        public void run() {
            try {
                if (count % 2 == 0) {
                    Thread.sleep(100);
                }
                if (count % 3 == 0) {
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (null != lock) {
                lock.lock("lockTest", 10, TimeUnit.SECONDS);
            }
            a--;
            if (null != lock) {
                lock.releaseLock("lockTest");
            }
            System.out.println(countDownLatch.getCount());
            countDownLatch.countDown();
        }
    }

    @RequestMapping(value = {"/api/admin/test/lockTest"}, method = RequestMethod.GET)
    public ResultModel lockTest() throws InterruptedException {
        a = 100;
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for (int i = 0; i < 100; i++) {
            new Thread(new LockTestInfo(countDownLatch, i, lock)).start();
//            new Thread(new LockTestInfo(countDownLatch, i, null)).start();
        }
        countDownLatch.await();
        System.out.println("a:" + a);
        return ResultModel.newSuccess();
    }

    @RequestRepeatCheck(keyPrefix = "cache:repeat:paramTest:", requestKeyType = "param", requestKeyName = "cacheKey")
    @PostMapping(value = {"/api/admin/test/repeatParamTest"})
    public ResultModel repeatParamTest(@RequestParam(value = "cacheKey", required = false) String cacheKey) {
        return ResultModel.newSuccess();
    }

    @RequestRepeatCheck(keyPrefix = "cache:repeat:bodyTest:", requestKeyType = "body", requestKeyName = "cacheKey")
    @PostMapping(value = {"/api/admin/test/repeatBodyTest"})
    public ResultModel repeatBodyTest(@RequestBody Map<String, Object> param) {
        return ResultModel.newSuccess();
    }

    @RequestRepeatCheck(keyPrefix = "cache:repeat:requestTest:", requestKeyType = "request", requestKeyName = "cacheKey")
    @PostMapping(value = {"/api/admin/test/repeatRequestTest"})
    public ResultModel repeatRequestTest(HttpServletRequest request) {
        return ResultModel.newSuccess();
    }

    //	@RequestRepeatCheck(keyPrefix = "cache:repeat:voTest:", requestKeyType = "body", timeoutSeconds = 3, requestKeyName = "cacheKey")
    @LoCacheable(cacheNames = "cache:locache:voTest:", key = "#indexVo.cacheKey", timeout = 10, timeUnit = TimeUnit.SECONDS)
    @PostMapping(value = {"/api/admin/test/repeatVoTest"})
    public ResultModel repeatVoTest(IndexVo indexVo) {
        System.out.println("hello indexVo");
        return ResultModel.newSuccess();
    }

    @ApiOperation("/查询用户信息")
    @PostMapping(value = {"/api/admin/test/localList"})
    public ResultModel localList(TestVo testVo) {
        System.out.println("/api/admin/test/localList,pid:" + testVo.getPid());
        List<Map<String, Object>> list = testService.localList(testVo);
        return ResultModel.newSuccess(list);
    }

    @PostMapping(value = {"/api/admin/test/localListTempCache"})
    public ResultModel localListTempCache(TestVo testVo) {
        System.out.println("/api/admin/test/localListTempCache,pid:" + testVo.getPid());
        List<Map<String, Object>> list = testService.localListTempCache(testVo);
        return ResultModel.newSuccess(list);
    }

    @PostMapping(value = {"/api/admin/test/deleteLocalList"})
    public ResultModel deleteLocalList(TestVo testVo) {
        System.out.println("/api/admin/test/deleteLocalList,pid:" + testVo.getPid());
        testService.deleteLocalList(testVo);
        return ResultModel.newSuccess();
    }

    @PostMapping(value = {"/api/admin/test/redisList"})
    public ResultModel redisList(TestVo testVo) {
        System.out.println("/api/admin/test/redisList,pid:" + testVo.getPid());
        List<Map<String, Object>> list = testService.redisList(testVo);
        return ResultModel.newSuccess(list);
    }

    @PostMapping(value = {"/api/admin/test/localBigDataList"})
    public ResultModel localBigDataList(TestVo testVo) {
        System.out.println("/api/admin/test/localBigDataList,pid:" + testVo.getPid());
        List<Map<String, Object>> list = testService.localListBigData(testVo);
        return ResultModel.newSuccess(list);
    }

    @PostMapping(value = {"/api/admin/test/deleteLocalBigDataList"})
    public ResultModel deleteLocalBigDataList(TestVo testVo) {
        System.out.println("/api/admin/test/deleteLocalBigDataList,pid:" + testVo.getPid());
        testService.deleteLocalListBigData(testVo);
        return ResultModel.newSuccess();
    }

    @PostMapping(value = {"/api/admin/test/redisListBigData"})
    public ResultModel redisListBigData(TestVo testVo) {
        System.out.println("/api/admin/test/redisListBigData,pid:" + testVo.getPid());
        List<Map<String, Object>> list = testService.redisListBigData(testVo);
        return ResultModel.newSuccess(list);
    }

    @PostMapping(value = {"/api/admin/test/test"})
    public ResultModel Test(IndexVo indexVo) {
        Map<String, Object> params = new HashMap<>();
        params.put("pid", "6");
        long t1 = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(500);
        for (int i = 0; i < 500; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
					/*	ResultModel resultModel = restTemplate
								.postForObject("http://localhost:8085/shop-api/api/admin/test/localList?pid=5", indexVo, ResultModel.class);*/
//						String url = "http://localhost:8085/shop-api/api/admin/test/redisList";
//						String url = "http://localhost:8085/shop-api/api/admin/test/localList";
                        String url = "http://localhost:8081/shop-api/api/admin/test/localList";
                        String result = HttpTest.adaptor.doPost(url, params);
                        if (CommonUtil.isNullOrEmpty(result)) {
                            log.error("get localList result error");
                        }
//						System.out.println("result:" + result);
//						System.out.println(JSONObject.toJSONString(resultModel));
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long t2 = System.currentTimeMillis();
        System.out.println("花费时长:" + (t2 - t1));


		/*String url = "http://localhost:8085/shop-api/api/admin/test/deleteLocalListTest";
		String result = HttpTest.adaptor.doPost(url, params);
		System.out.println(JSONObject.toJSONString(result));*/
        return ResultModel.newSuccess();
    }

    @PostMapping(value = {"/api/admin/test/testKafka"})
    public ResultModel testKafka(String message) {
        kafkaComponent.sendMessage(message);
        return ResultModel.newSuccess();

    }

    @RequestMapping(value = {"/api/admin/test/redisSetTest"}, method = RequestMethod.GET)
    public ResultModel redisSetTest() {
        String[] userArray = {"ua:430050", "ut:1103", "ua:430050"};
        stringRedisTemplate.delete("redisSetTest");
        stringRedisTemplate.opsForSet().add("redisSetTest", userArray);
        boolean userTypeSetExists = stringRedisTemplate.opsForSet().isMember("redisSetTest", "ut:1103");
        return ResultModel.newSuccess(userTypeSetExists);
    }


    @RequestMapping(value = {"/api/admin/test/asyncTest"}, method = RequestMethod.GET)
    public ResultModel asyncTest() {
        System.out.println(LocalDateUtil.localDateTimeFormat(LocalDateTime.now(), LocalDateUtil.FORMAT_PATTERN1));
        testService.asyncTest();
        System.out.println(LocalDateUtil.localDateTimeFormat(LocalDateTime.now(), LocalDateUtil.FORMAT_PATTERN1));
        return ResultModel.newSuccess();
    }
}
